#ifndef _WX_RICHTEXTFORMATDLG_H_
#define _WX_RICHTEXTFORMATDLG_H_

#include "wx/defs.h"
#include "wx/propdlg.h"
#include "wx/bookctrl.h"
#include <wx/htmllbox.h>
#include "wx/richtext/richtextbuffer.h"
#include "wx/richtext/richtextstyles.h"

class wxRichTextFormattingDialog;
class wxImageList;

#define wxRICHTEXT_FORMAT_STYLE_EDITOR      0x0001
#define wxRICHTEXT_FORMAT_FONT              0x0002
#define wxRICHTEXT_FORMAT_TABS              0x0004
#define wxRICHTEXT_FORMAT_BULLETS           0x0008
#define wxRICHTEXT_FORMAT_INDENTS_SPACING   0x0010
#define wxRICHTEXT_FORMAT_LIST_STYLE        0x0020

#define wxRICHTEXT_FORMAT_HELP_BUTTON       0x0100

enum {
  wxRICHTEXT_BULLETINDEX_NONE = 0,
  wxRICHTEXT_BULLETINDEX_ARABIC,
  wxRICHTEXT_BULLETINDEX_UPPER_CASE,
  wxRICHTEXT_BULLETINDEX_LOWER_CASE,
  wxRICHTEXT_BULLETINDEX_UPPER_CASE_ROMAN,
  wxRICHTEXT_BULLETINDEX_LOWER_CASE_ROMAN,
  wxRICHTEXT_BULLETINDEX_OUTLINE,
  wxRICHTEXT_BULLETINDEX_SYMBOL,
  wxRICHTEXT_BULLETINDEX_BITMAP,
  wxRICHTEXT_BULLETINDEX_STANDARD
};

#define wxRICHTEXT_FORMAT_PARAGRAPH         (wxRICHTEXT_FORMAT_INDENTS_SPACING | wxRICHTEXT_FORMAT_BULLETS | wxRICHTEXT_FORMAT_TABS | wxRICHTEXT_FORMAT_FONT)
#define wxRICHTEXT_FORMAT_CHARACTER         (wxRICHTEXT_FORMAT_FONT)
#define wxRICHTEXT_FORMAT_STYLE             (wxRICHTEXT_FORMAT_PARAGRAPH | wxRICHTEXT_FORMAT_STYLE_EDITOR)

class wxRichTextFormattingDialogFactory: public wxObject {
  public:
    wxRichTextFormattingDialogFactory() {}
    virtual ~wxRichTextFormattingDialogFactory() {}
    virtual bool CreatePages( long pages, wxRichTextFormattingDialog* dialog );
    virtual wxPanel* CreatePage( int page, wxString& title, wxRichTextFormattingDialog* dialog );
    virtual int GetPageId( int i ) const;
    virtual int GetPageIdCount() const;
    virtual int GetPageImage( int ( id ) ) const { return -1; }
    virtual bool ShowHelp( int ( page ), wxRichTextFormattingDialog* ( dialog ) ) { return false; }
    virtual bool SetSheetStyle( wxRichTextFormattingDialog* dialog );
    virtual bool CreateButtons( wxRichTextFormattingDialog* dialog );
};

class wxRichTextFormattingDialog: public wxPropertySheetDialog {
    DECLARE_CLASS( wxRichTextFormattingDialog )
  public:
    wxRichTextFormattingDialog() { Init(); }

    wxRichTextFormattingDialog( long flags, wxWindow* parent, const wxString& title = wxGetTranslation( wxT( "Formatting" ) ), wxWindowID id = wxID_ANY,
                                const wxPoint& pos = wxDefaultPosition, const wxSize& sz = wxDefaultSize,
                                long style = wxDEFAULT_DIALOG_STYLE ) {
      Init();
      Create( flags, parent, title, id, pos, sz, style );
    }

    ~wxRichTextFormattingDialog();

    void Init();

    bool Create( long flags, wxWindow* parent, const wxString& title = wxGetTranslation( wxT( "Formatting" ) ), wxWindowID id = wxID_ANY,
                 const wxPoint& pos = wxDefaultPosition, const wxSize& sz = wxDefaultSize,
                 long style = wxDEFAULT_DIALOG_STYLE );
    virtual bool GetStyle( wxRichTextCtrl* ctrl, const wxRichTextRange& range );
    virtual bool SetStyle( const wxTextAttrEx& style, bool update = true );
    virtual bool SetStyleDefinition( const wxRichTextStyleDefinition& styleDef, wxRichTextStyleSheet* sheet, bool update = true );
    virtual wxRichTextStyleDefinition* GetStyleDefinition() const { return m_styleDefinition; }
    virtual wxRichTextStyleSheet* GetStyleSheet() const { return m_styleSheet; }
    virtual bool UpdateDisplay();
    virtual bool ApplyStyle( wxRichTextCtrl* ctrl, const wxRichTextRange& range, int flags = wxRICHTEXT_SETSTYLE_WITH_UNDO | wxRICHTEXT_SETSTYLE_OPTIMIZE );
    const wxTextAttrEx& GetAttributes() const { return m_attributes; }
    wxTextAttrEx& GetAttributes() { return m_attributes; }
    void SetAttributes( const wxTextAttrEx& attr ) { m_attributes = attr; }
    virtual bool TransferDataToWindow();
    virtual bool TransferDataFromWindow();
    void OnTabChanged( wxBookCtrlEvent& event );
    void OnHelp( wxCommandEvent& event );
    void SetImageList( wxImageList* imageList ) { m_imageList = imageList; }
    wxImageList* GetImageList() const { return m_imageList; }
    static void SetFormattingDialogFactory( wxRichTextFormattingDialogFactory* factory );
    static wxRichTextFormattingDialogFactory* GetFormattingDialogFactory() { return ms_FormattingDialogFactory; }
    static wxRichTextFormattingDialog* GetDialog( wxWindow* win );
    static wxTextAttrEx* GetDialogAttributes( wxWindow* win );
    static wxRichTextStyleDefinition* GetDialogStyleDefinition( wxWindow* win );
    static bool ShowToolTips() { return sm_showToolTips; }
    static void SetShowToolTips( bool show ) { sm_showToolTips = show; }
    void AddPageId( int id ) { m_pageIds.Add( id ); }

  protected:

    wxImageList*                                m_imageList;
    wxTextAttrEx                                m_attributes;
    wxRichTextStyleDefinition*                  m_styleDefinition;
    wxRichTextStyleSheet*                       m_styleSheet;
    wxArrayInt                                  m_pageIds; // mapping of book control indexes to page ids

    static wxRichTextFormattingDialogFactory*   ms_FormattingDialogFactory;
    static bool                                 sm_showToolTips;

    DECLARE_EVENT_TABLE()
};

class wxRichTextFontPreviewCtrl : public wxWindow {
  public:
    wxRichTextFontPreviewCtrl( wxWindow *parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& sz = wxDefaultSize, long style = 0 ) {
      if( ( style & wxBORDER_MASK ) == wxBORDER_DEFAULT ) {
        style |= wxBORDER_SUNKEN;
      }
      wxWindow::Create( parent, id, pos, sz, style );
      SetBackgroundColour( *wxWHITE );
      m_textEffects = 0;
    }

    void SetTextEffects( int effects ) { m_textEffects = effects; }
    int GetTextEffects() const { return m_textEffects; }

  private:
    int m_textEffects;

    void OnPaint( wxPaintEvent& event );
    DECLARE_EVENT_TABLE()
};

class wxRichTextColourSwatchCtrl: public wxControl {
    DECLARE_CLASS( wxRichTextColourSwatchCtrl )
  public:
    wxRichTextColourSwatchCtrl( wxWindow* parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = 0 );
    ~wxRichTextColourSwatchCtrl();
    void OnMouseEvent( wxMouseEvent& event );
    void SetColour( const wxColour& colour ) { m_colour = colour; SetBackgroundColour( m_colour ); }
    wxColour& GetColour() { return m_colour; }
    virtual wxSize DoGetBestSize() const { return GetSize(); }
  protected:
    wxColour    m_colour;
    DECLARE_EVENT_TABLE()
};

class wxRichTextFontListBox: public wxHtmlListBox {
    DECLARE_CLASS( wxRichTextFontListBox )
    DECLARE_EVENT_TABLE()

  public:
    wxRichTextFontListBox() {
      Init();
    }
    wxRichTextFontListBox( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition,
                           const wxSize& size = wxDefaultSize, long style = 0 );
    virtual ~wxRichTextFontListBox();

    void Init() {
    }

    bool Create( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition,
                 const wxSize& size = wxDefaultSize, long style = 0 );

    /// Creates a suitable HTML fragment for a font
    wxString CreateHTML( const wxString& facename ) const;

    /// Get font name for index
    wxString GetFaceName( size_t i ) const ;

    /// Set selection for string, returning the index.
    int SetFaceNameSelection( const wxString& name );

    /// Updates the font list
    void UpdateFonts();

    /// Does this face name exist?
    bool HasFaceName( const wxString& faceName ) const { return m_faceNames.Index( faceName ) != wxNOT_FOUND; }

    /// Returns the array of face names
    const wxArrayString& GetFaceNames() const { return m_faceNames; }

  protected:
    /// Returns the HTML for this item
    virtual wxString OnGetItem( size_t n ) const;

  private:

    wxArrayString           m_faceNames;
};

#endif
